﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Diagnostics;


namespace OneKeyUnistalliTunes
{
    /// <summary>
    /// 苹果应用程序卸载器(主要就是卸载iTunes相关产品)
    /// </summary>
    public class AppleAppUnistaller
    {
        /// <summary>
        /// 苹果待卸载程序名字
        /// </summary>
        private string[] appleAppNames = { "Apple Mobile Device Support", "iTunes", "QuickTime", "Bonjour", 
                                             "Apple Software Update", "Apple Application Support" };

        /// <summary>
        /// 需要删除的iTunes音乐文件夹
        /// </summary>
        private string iTunesMusicFolder = "\\iTunes";//"My Music\\iTunes\\";

        /// <summary>
        /// 本机搜索到的苹果iTunes相关程序
        /// </summary>
        private List<AppUnistallInfo> appleiTunesApps = new List<AppUnistallInfo>();

        /// <summary>
        /// 出错日志
        /// </summary>
        private string log = string.Empty;

        private static object locker = new object();

        /// <summary>
        /// 是否匹配苹果AppleAppNames里面的名字
        /// </summary>
        /// <param name="displayName"></param>
        /// <returns></returns>
        private bool IsMatchAppleAppName(string displayName)
        {
            if (string.IsNullOrEmpty(displayName))
                return false;

            foreach (string appName in this.appleAppNames)
            {
                if (appName.ToLower() == displayName.ToLower())
                    return true;
            }

            return false;
        }

        /// <summary>
        /// 查找本机已安装的iTunes相关程序卸载信息
        /// </summary>
        private void FindAppleAppUninstallInfo()
        {
            try
            {
                Microsoft.Win32.RegistryKey installerProductsReg =
               Microsoft.Win32.Registry.LocalMachine.OpenSubKey("SOFTWARE")
               .OpenSubKey("Microsoft").OpenSubKey("Windows").OpenSubKey("CurrentVersion")
               .OpenSubKey("Installer").OpenSubKey("UserData")
               .OpenSubKey("S-1-5-18").OpenSubKey("Products");
                string[] Names = installerProductsReg.GetSubKeyNames();

                for (int i = 0; i < Names.Length; i++)
                {
                    Microsoft.Win32.RegistryKey tempReg = installerProductsReg.OpenSubKey(Names[i]).OpenSubKey("InstallProperties");
                    if (tempReg != null)
                    {
                        string displayName = tempReg.GetValue("DisplayName") as string;
                        if (this.IsMatchAppleAppName(displayName))
                        {
                            AppUnistallInfo unistallInfo = new AppUnistallInfo();
                            unistallInfo.DisplayName = displayName;
                            object obj = tempReg.GetValue("UninstallString");
                            if (obj == null)
                                unistallInfo.UninstallString = string.Empty;
                            else
                                unistallInfo.UninstallString = obj.ToString();

                            this.appleiTunesApps.Add(unistallInfo);

                            if (this.appleiTunesApps.Count == this.appleAppNames.Length)
                                break;//减少检测时间
                        }
                    }
                }

            }
            catch (Exception e)
            {
                this.log += e.Message + Environment.NewLine;
                System.Diagnostics.Debug.WriteLine(e);
            }

        }

        /// <summary>
        /// 要删除的项目数
        /// </summary>
        public int Count
        {
            get { return appleiTunesApps.Count + 1; }
        }

        /// <summary>
        /// 错误日志
        /// </summary>
        public string ErrorLog
        {
            get { return this.log; }
        }

        /// <summary>
        /// 卸载进度事件
        /// </summary>
        public event EventHandler<UnistallProgressArgs> UninstallProgress;

        protected void OnUninstallProgress(UnistallProgressArgs args)
        {
            if (this.UninstallProgress != null)
            {
                EventHandler<UnistallProgressArgs> handler = this.UninstallProgress;
                handler(this, args);
            }
        }
        /// <summary>
        /// 初始构造,搜索本机已安装iTunes程序信息
        /// </summary>
        public AppleAppUnistaller()
        {
            this.FindAppleAppUninstallInfo();
        }

        /// <summary>
        /// 开始卸载操作
        /// </summary>
        public void StartUnistall()
        {
            UnistallProgressArgs args = new UnistallProgressArgs();
            args.Count = this.appleiTunesApps.Count;
            args.CurrentCount = 0;

            if (this.appleiTunesApps.Count == 0)
            {
                this.log += "你的系统已没有安装iTunes相关程序" + Environment.NewLine;
                args.IsFinished = true;
                args.Log = this.log;
                this.OnUninstallProgress(args);
            }
            else
            {
                Thread t = new Thread(new ThreadStart(delegate()
                {
                    foreach (string appName in this.appleAppNames)
                    {
                        foreach (AppUnistallInfo info in this.appleiTunesApps)
                        {
                            if (appName == info.DisplayName)
                            {
                                try
                                {
                                    using (Process p = new Process())
                                    {
                                        ProcessStartInfo startInfo = new ProcessStartInfo();
                                        ///quiet /passive /qn
                                        //真吐血的参数啊
                                        string arguments = null;
                                        if (!info.UninstallString.Contains("X{"))
                                            arguments = "/x{" + info.UninstallString.Split("/".ToCharArray())[1].Split("I{".ToCharArray())[2] + " /qb /norestart";
                                        else
                                            arguments = "/" + info.UninstallString.Split("/".ToCharArray())[1];

                                        startInfo.FileName = info.UninstallString.Split("/".ToCharArray())[0];
                                        startInfo.Arguments = arguments;
                                        p.StartInfo = startInfo;
                                        p.Start();
                                        DateTime installTime = DateTime.Now;

                                        args.Name = info.DisplayName;
                                       
                                        this.OnUninstallProgress(args);

                                        while (!p.HasExited)
                                        {
                                            System.Threading.Thread.Sleep(100);
                                            //超时5分钟
                                            if (installTime.AddMinutes(5) < DateTime.Now)
                                                break;
                                        }

                                        args.CurrentCount += 1;
                                        if (args.CurrentCount != this.appleiTunesApps.Count)
                                            args.IsFinished = false;
                                        else
                                        {
                                            args.IsFinished = true;
                                            this.log = "iTunes相关组件卸载完毕,如果有需要可以重启计算机";
                                            args.Log = this.log;
                                        }
                                        this.OnUninstallProgress(args);
                                       
                                        Thread.Sleep(800);
                                        //System.Diagnostics.Process[] processes = System.Diagnostics.Process.GetProcessesByName("msiexec.exe");
                                        //foreach (Process msp in processes)
                                        //{
                                        //    msp.Kill();
                                        //}
                                                                              
                                    }
                                }
                                catch (Exception e)
                                {
                                    System.Diagnostics.Debug.WriteLine(e);
                                    this.log += e.Message + Environment.NewLine;

                                    args.IsFinished = false;
                                    args.Log += this.log;
                                    this.OnUninstallProgress(args);
                                }
                            }
                        }
                    }
                }));
                t.IsBackground = true;
                t.Start();
            }
        }

        /// <summary>
        /// 删除iTunes文件夹
        /// </summary>
        /// <returns></returns>
        public bool DeleteiTunesFolder()
        {
            string myMusicFolder = Environment.GetFolderPath(Environment.SpecialFolder.MyMusic);
            this.iTunesMusicFolder = myMusicFolder + this.iTunesMusicFolder;
            if (System.IO.Directory.Exists(this.iTunesMusicFolder))
            {
                try
                {
                    System.IO.Directory.Delete(this.iTunesMusicFolder, true);

                    return true;
                }
                catch (Exception e)
                {
                    System.Diagnostics.Debug.WriteLine(e);

                    return false;
                }
            }

            return true;
        }
    }

    /// <summary>
    ///卸载进度事件参数
    /// </summary>
    public class UnistallProgressArgs : EventArgs
    {
        /// <summary>
        /// 当前卸载程序名字
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// 总的需要卸载数
        /// </summary>
        public int Count { get; set; }

        /// <summary>
        /// 卸载相关信息
        /// </summary>
        public string Log { get; set; }

        /// <summary>
        /// 是否完成
        /// </summary>
        public bool IsFinished { get; set; }

        /// <summary>
        /// 当前卸载数
        /// </summary>
        public int CurrentCount { get; set; }
    }

    /// <summary>
    /// 应用程序卸载信息
    /// </summary>
    public class AppUnistallInfo
    {
        public string DisplayName { get; set; }

        public string UninstallString { get; set; }
    }
}
